/*+**************************************************************************/
/***                                                                      ***/
/***   This file is distributed under a BSD license.                      ***/
/***   See LICENSE.txt for details.                                       ***/
/***                                                                      ***/
/**************************************************************************+*/

/****************************************************************************/
/***                                                                      ***/
/***   Sprite Renderer                                                    ***/
/***                                                                      ***/
/****************************************************************************/

asc
{
  cbuffer FR063StaticParticleVSPara : register(c0) : slot vs 0
  {
    row_major float4x4 mvp;     // rotation for light vector (not really needed)
    float4 di;
    float4 dj;
  };
  cbuffer FR063StaticParticlePSPara : register(c0) : slot ps 0
  {    
    float4 fade0col;
  };
}

material FR063StaticParticleShader
{
  prepare
  {
    VertexShader = VS();
    PixelShader = PS(); 
  }
  
  vs
  {
    asc vs_3_0                 // hlsl code
    {
      use FR063StaticParticleVSPara;
      
      void main
      (
        in float3 in_uva    : TEXCOORD1,
        in float4 in_pos    : POSITION,
        in float4 in_color  : COLOR0,
        in float4 in_scale  : TEXCOORD0,
        in float4 in_uvrect : TEXCOORD2,        
        in float1 in_fade   : TEXCOORD3,        
        out float4 out_uv0  : TEXCOORD0,
        out float4 out_fade : TEXCOORD1,
        out float4 out_col  : COLOR0,
        out float4 out_pos  : POSITION,
      )
      {
        out_uv0.xy = in_uvrect.xy + in_uva.xy*in_uvrect.zw;
        out_uv0.zw = in_scale.zw;
        float mc   = cos(in_pos.w+in_uva.z);
        float ms   = sin(in_pos.w+in_uva.z);
        float3 pos = in_pos.xyz 
                   + di.xyz*in_scale.x*ms + dj.xyz*in_scale.y*mc
                   + di.xyz*in_scale.x*mc - dj.xyz*in_scale.y*ms;
        out_pos    = mul(float4(pos,1),mvp);
        out_fade   = in_fade.xxxx;
        out_col    = in_color;
      }
    }
  }

  ps 
  {
    asc ps_3_0
    {
      use FR063StaticParticlePSPara;

      sampler2D s0 : register(s0);
      
      void main
      (
        in  float4 in_uv0  : TEXCOORD0,
        in  float1 in_fade : TEXCOORD1,
        in  float4 in_col  : COLOR0,
        out float4 result  : COLOR0,
      )
      {
        result = tex2D(s0,in_uv0.xy);
        result = lerp(fade0col,in_col*result,in_fade.x);
      }
    }    
  }
};




/****************************************************************************/
/***                                                                      ***/
/***   Ball Renderer                                                    ***/
/***                                                                      ***/
/****************************************************************************/

asc
{
  cbuffer FR063BallVSPara : register(c0) : slot vs 0
  {
    row_major float4x4 mvp;     // model, view, projection
    row_major float4x4 mv;      // model, view
    float4 di;
    float4 dj;
  };
  cbuffer FR063BallPSPara : register(c0) : slot ps 0
  {
    row_major float4x4 proj;     // projection
    float4             lightpos;
    float4             campos;    
    float4             ambcol;
    float4             diffcol;
    float4             speccol;
    float4             specprm; //x=hardness, y=power
  };
}

material FR063BallShader
{
  prepare
  {
    VertexShader = VS();
    PixelShader = PS(); 
  }
  
  vs
  {
    asc vs_3_0                 // hlsl code
    {
      use FR063BallVSPara;
      
      void main
      (
        in float3 in_uva    : TEXCOORD0,        
        in float4 in_pos    : POSITION,        
        out float4 out_uvr  : COLOR0,                
        out float4 out_xyzw : COLOR1,
        out float4 out_pos  : POSITION
      )
      {
        float mc    = cos(in_uva.z);
        float ms    = sin(in_uva.z);
        float3 pos3 = in_pos.xyz + di.xyz*in_pos.w*ms + dj.xyz*in_pos.w*mc + di.xyz*in_pos.w*mc - dj.xyz*in_pos.w*ms;                        
        out_pos     = mul(float4(pos3,1),mvp);
        out_xyzw    = mul(float4(pos3,1),mv);
        out_uvr     = float4(in_uva.x, in_uva.y, in_pos.w, 1.0);
      }
    }
  }

  ps 
  {
    asc ps_3_0
    {
      use FR063BallPSPara;
            
      float4 blinn_phong( in float3 normal, in float3 viewer, in float3 light )
      {              
          // Compute the half vector
          float3 half_vector = normalize(light + viewer);
       
          // Compute the angle between the half vector and normal
          float  HdotN = max( 0.0f, dot( half_vector, normal ) );
       
          // Compute the specular colour
          float3 specular = speccol.xyz * pow( HdotN, specprm.x );
       
          // Compute the diffuse term
          float3 diffuse = diffcol.xyz * max( 0.0f, dot( normal, light ) );
       
          // Determine the final colour    
          return float4( ambcol.xyz + diffuse + specular, 1.0f );
      }            
            
      void main
      (
        in  float4 in_uvr  : COLOR0,        
        in  float4 in_xyzw : COLOR1,
        out float4 result  : COLOR0,
        out float  depth   : DEPTH
      )
      {              
        float d=1-sqrt(in_uvr.x*in_uvr.x+in_uvr.y*in_uvr.y);        
        clip(d);                        
        float4 t=in_xyzw;
        t.z = t.z-d*in_uvr.z;       
        float3 n=float3(in_uvr.x, in_uvr.y, -d);                               
        float3 v=-t.xyz;
        float3 l=lightpos.xyz-t.xyz;
        v=normalize(v);
        l=normalize(l);
        result = blinn_phong(n,v,l);
        
        t = mul(t,proj);
        depth=t.z/t.w;        
        
      }
    }    
  }
};


/****************************************************************************/
/***                                                                      ***/
/***   SpriteExt Renderer                                                 ***/
/***                                                                      ***/
/****************************************************************************/

asc
{
  cbuffer StaticParticleExtVSPara : register(c0) : slot vs 0
  {
    row_major float4x4 mvp;     // rotation for light vector (not really needed)
   // float4 di;  //move into stream, because it is different per Sprite
//    float4 dj;
  };
  cbuffer StaticParticleExtPSPara : register(c0) : slot ps 0
  {
    float4 col;
    float4 fade0col;
  };
  permute StaticParticleExtPSPerm
  {
    Tex1;
  };
}

material StaticParticleShaderExt
{
  prepare
  {
    VertexShader = VS();
    PixelShader = PS(Texture[1]?1:0); 
  }
  
  vs
  {
    asc vs_3_0                 // hlsl code
    {
      use StaticParticleExtVSPara;
      
      void main
      (
        in float3 in_uva    : TEXCOORD1,
        in float4 in_pos    : POSITION,
        in float4 in_scale  : TEXCOORD0,
        in float4 in_uvrect : TEXCOORD2,
        in float1 in_fade   : TEXCOORD3,
        in float4 in_di     : TEXCOORD4,
        in float4 in_dj     : TEXCOORD5,        
        in float4 in_color  : COLOR0,

        out float4 out_uv0  : TEXCOORD0,
        out float4 out_col  : COLOR0,
        out float4 out_colx : COLOR1,
        out float4 out_pos  : POSITION,
      )
      {
        out_uv0.xy = in_uvrect.xy + in_uva.xy*in_uvrect.zw;
        out_uv0.zw = in_scale.zw;
        float mc = cos(in_pos.w+in_uva.z);
        float ms = sin(in_pos.w+in_uva.z);
        float3 pos = in_pos.xyz 
                   + in_di.xyz*in_scale.x*ms + in_dj.xyz*in_scale.y*mc
                   + in_di.xyz*in_scale.x*mc - in_dj.xyz*in_scale.y*ms;
        out_pos = mul(float4(pos,1),mvp);
        out_col = in_fade.xxxx;
        out_colx = in_color;
      }
    }
  }

  ps 
  {
    asc ps_3_0
    {
      use StaticParticleExtPSPerm;
      use StaticParticleExtPSPara;

      sampler2D s0 : register(s0);
      sampler2D s1 : register(s1) : pif(Tex1);
      
      void main
      (
        in float4 uv0 : TEXCOORD0,
        in float4 col0 : COLOR0,
        in float4 col1 : COLOR1,
        out float4 result : COLOR0,
      )
      {
        result = tex2D(s0,uv0.xy);
        pif(Tex1)
          result *= tex2D(s1,uv0.zw);
        result = lerp(fade0col,col*result,col0.x)*col1;
      }
    }    
  }
};
